package com.zl.shirodemo.util;

import java.util.Date;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.zl.shirodemo.entity.SysUser;
import com.zl.shirodemo.mapper.SysUserMapper;

/**
 * 不明白jwt的看这篇
 * https://www.jianshu.com/p/576dbf44b2ae
 */
@Component
public class JWTUtil {
    @Value("${jwt.expireTime}")
    private long expireTime;
    
    @Autowired
    SysUserMapper sysUserMapper;
    
    private static final String USERID = "userId";
    
    /**
     * @param userId
     * @param secret
     * @return
     */
    public String getToken(int userId, String secret) {
        Date date = new Date(System.currentTimeMillis() + expireTime);
        Algorithm algorithm = Algorithm.HMAC256(secret);
        return JWT.create().withClaim(USERID, userId).withExpiresAt(date).sign(algorithm);
    }
    
    /**
     * 验证token的合法性
     * 1.从token获取userid, 这个userid是不可靠的
     * 2. 根据userid 从数据库查出来用户密码（也就是用来签名的密码)
     * 3.重新生成token
     * 4. 比较传来的token和重新生成token是否一致，来验证数据是否被改过了
     *
     * @param token
     * @return
     */
    public boolean verify(String token) {
        //外层的try catch 是为了应对各种无法处理的情况，这些都是因为数据做出了改变导致的，所以都认为是不合法请求
        try {
            //通过token获取用户id
            DecodedJWT decode = JWT.decode(token);
            int userId = decode.getClaim(USERID).asInt();
            //获取token的过期时间
            Date expiresAt = decode.getExpiresAt();
            if(expiresAt.compareTo(new Date()) < 0){
                return false;
            }
            
            SysUser sysUser = sysUserMapper.selectByPrimaryKey(userId);
            String secret = sysUser.getPassowrd();
            String tokenGeneratedByBE = JWT.create().withClaim(USERID, userId).withExpiresAt(expiresAt).sign(Algorithm.HMAC256(secret));
            if (!token.equals(tokenGeneratedByBE)) {
                return false;
            }
        } catch (Exception e) {
            return false;
        }
        return true;
    }
    
    /**
     * 从token中解析出userid
     * @param token
     * @return
     */
    public int getUserIdByToken(String token) {
        int userId = JWT.decode(token).getClaim(USERID).asInt();
        return userId;
    }
}
